<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<style>
    * {
        padding: 0;
        margin: 0;
    }

    .table {
        position: absolute;
        width: 800px;
        height: 450px;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background-color: rgb(2, 108, 53)
    }
</style>

<body>
    <div class="table">
        <canvas id="canvas"></canvas>
    </div>

    <script>
        var canvas = document.getElementById('canvas')
        var cvsCtx = canvas.getContext('2d')
        canvas.width = 800
        canvas.height = 450
        var color = ["#f20", "#342", "#123", "#999", "#742"]
        var holes = [{
            x: 0,
            y: 0
        }, {
            x: 800,
            y: 0
        }, {
            x: 0,
            y: 450
        }, {
            x: 800,
            y: 450
        }]

        function getRandomInt(min, max) {
            return Math.floor(Math.random() * (max - min + 1) + min)
        }
        var originBall = {
            vx: 0,
            vy: 0,
            angle: 0,
            color: "#fff",
            x: 100,
            y: 220
        }
        var targetBall = {
            vx: 0,
            vy: 0,
            angle: 0,
            color: color[getRandomInt(0, color.length - 1)],
            x: getRandomInt(100, canvas.width - 50),
            y: getRandomInt(20, canvas.height - 50)
        }
        let obstacle = 0.96
        let originV = 40
        let coefficient = 0.85
        let isShot = false
        let isBallMove = false
        var Billiard = function () { }
        Billiard.prototype = {
            init() {
                drawBall(originBall)
                drawBall(targetBall)

                drawHole()
                updataGame()
            },




        }

        var billiard = new Billiard();
        billiard.init();
        function drawHole() {
            for (const {
                x,
                y
            } of holes) {
                cvsCtx.beginPath();
                cvsCtx.fillStyle = "#000"
                cvsCtx.arc(x, y, 50, 0, Math.PI * 2, true)
                cvsCtx.fill();
                cvsCtx.closePath();
            }
        }
        function updataGame() {
            cvsCtx.clearRect(0, 0, 900, 450)
            drawBall(originBall)
            drawBall(targetBall)
            drawHole()
            judgeBall()
            judgeState()
            if (isShot) {
                shot(originBall)
            }
            if (!isBallMove) {
                drawRod(originBall)
            }
            requestAnimationFrame(updataGame);
        }
        function judgeState() {
            if (judgeDistance(originBall)) {
                originBall.x = -2000
                alert("你输了")
                window.location.reload()
            }
            if (judgeDistance(targetBall)) {
                targetBall.x = -2000
                alert("YOU WIN")
                window.location.reload()
            }

        }

        function judgeDistance(obj) {
            for (const e of holes) {
                let distance = Math.sqrt((e.y - obj.y) ** 2 + (e.x - obj.x) ** 2)
                if (Math.abs(distance) <= 50) {
                    return true
                }
            }
        }
        function drawBall(obj) {
            cvsCtx.beginPath();
            cvsCtx.fillStyle = obj.color
            cvsCtx.arc(obj.x, obj.y, 20, 0, Math.PI * 2, true)
            cvsCtx.fill();
            cvsCtx.closePath();
        }
        function judgeBall() {

            let arr = [originBall, targetBall]

            let vx = originBall.vx
            let vy = originBall.vy
            let distance = Math.sqrt((arr[0].y - arr[1].y) ** 2 + (arr[0].x - arr[1].x) ** 2)
            if (distance <= 46) {
                let bx = Math.abs(targetBall.vx);
                let by = Math.abs(targetBall.vy);
                let tx = Math.abs(originBall.vx);
                let ty = Math.abs(originBall.vy);
                originBall.vx = (bx + tx) / 2;
                originBall.vy = (by + ty) / 2;
                targetBall.vx = -(bx + tx) / 2;
                targetBall.vy = -(by + ty) / 2;

            }
            for (const item of arr) {
                if (item.y <= 20 || item.y >= 430) {
                    item.y >= 430 ? item.y -= 0.1 : item.y += 0.1
                    item.vy *= -coefficient
                    item.vx *= -coefficient
                }
                if (item.x <= 20 || item.x >= 780) {
                    item.x >= 780 ? item.x -= 0.1 : item.x += 0.1
                    item.vx *= -coefficient
                    item.vy *= -coefficient
                }
            }

            isBallMove = arr.some(function (e) {
                return Math.abs(e.vx) >= 0.01
            });
            console.log(isBallMove);
            [originBall, targetBall] = arr

        }

        function shot(bar) {
            let arr = [originBall, targetBall]
            arr = arr.map(function (bar) {
                bar.vx *= obstacle
                bar.vy *= obstacle
                bar.x += bar.vx
                bar.y -= bar.vy
                return bar
            })
            //    console.log(originBall.x,targetBall.x);

            [originBall, targetBall] = arr
        }

        canvas.onmousemove = function (e) {
            mouseX = e.offsetX;
            mouseY = e.offsetY;
            let x = mouseX - originBall.x;
            let y = -(mouseY - originBall.y);
            originBall.angle = Math.atan2(y, x)
        }
        canvas.onmousedown = function (e) {
            if (!isBallMove) {
                originBall.vy = Math.sin(originBall.angle) * originV
                originBall.vx = Math.cos(originBall.angle) * originV
                isShot = true
                shot(originBall)
            }
        }
        function drawRod(obj) {
            cvsCtx.beginPath();
            cvsCtx.strokeStyle = '"#fff';
            cvsCtx.lineWidth = 10;
            var targetX = obj.x - 260 * Math.cos(obj.angle)
            var targetY = (obj.y + 260 * Math.sin(obj.angle))
            cvsCtx.moveTo(targetX, targetY);
            cvsCtx.lineTo(obj.x - 50 * Math.cos(obj.angle), obj.y + 50 * Math.sin(obj.angle));
            cvsCtx.stroke()
        }
    </script>
</body>

</html>